# -*- coding: iso-8859-1 -*-
# file Geometry.py
# author Rocco Martino
#
############################################################################
#    Copyright (C) 2015 by Rocco Martino                                   #
#    martinorocco@gmail.com                                                #
#                                                                          #
#    This program is free software; you can redistribute it and/or modify  #
#    it under the terms of the GNU Lesser General Public License as        #
#    published by the Free Software Foundation; either version 2.1 of the  #
#    License, or (at your option) any later version.                       #
#                                                                          #
#    This program is distributed in the hope that it will be useful,       #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#    GNU Lesser General Public License for more details.                   #
#                                                                          #
#    You should have received a copy of the GNU Lesser General Public      #
#    License along with this program; if not, write to the                 #
#    Free Software Foundation, Inc.,                                       #
#    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             #
############################################################################

############################################################################
from . import Drawable
from mathutils import Vector, Matrix
############################################################################




############################################################################
# ........................................................................ #
# ........................................................................ #
############################################################################




############################################################################
# ........................................................................ #
class Geometry(Drawable.Drawable):





############################################################################
    Matrix = None
############################################################################









############################################################################
    def __init__(self, obj, data, matrix=None):
        super(Geometry, self).__init__(obj, data)

        self.ClassName = "osg::Geometry"


        if matrix == None:
            matrix = Matrix()
            matrix.identity()


        self.Matrix = matrix
############################################################################




############################################################################
    def writeData(self, writer):

        super(Geometry, self).writeData(writer)



        vertex_array = self.readVertexArray()

        writer.moveIn("PrimitiveSetList 1")
        writer.writeLine("DrawArrays GL_TRIANGLES 0 0 %d" % len(vertex_array))
        writer.moveOut("PrimitiveSetList 1")



        writer.moveIn("VertexData")


        array_id = self.Data.VertexID.generate()
        array_len = len(vertex_array)

        writer.moveIn("Array TRUE ArrayID %d Vec3fArray %d" %(array_id, array_len))

        for v in vertex_array:
            tmp = self.Matrix * v
            writer.writeLine("%f %f %f" %(tmp.x, tmp.y, tmp.z))

        writer.moveOut("Array TRUE ArrayID %d Vec3fArray %d" %(array_id, array_len))


        writer.writeLine("Indices FALSE")
        writer.writeLine("Binding BIND_PER_VERTEX")
        writer.writeLine("Normalize 0")


        writer.moveOut("VertexData")





        normal_array = self.readNormalArray()

        writer.moveIn("NormalData")


        array_id = self.Data.VertexID.generate()
        array_len = len(normal_array)

        writer.moveIn("Array TRUE ArrayID %d Vec3fArray %d" %(array_id, array_len))

        for v in normal_array:
            writer.writeLine("%f %f %f" %(v.x, v.y, v.z))

        writer.moveOut("Array TRUE ArrayID %d Vec3fArray %d" %(array_id, array_len))


        writer.writeLine("Indices FALSE")
        writer.writeLine("Binding BIND_PER_VERTEX")
        writer.writeLine("Normalize 0")


        writer.moveOut("NormalData")






        color_array = self.readColorArray()

        writer.moveIn("ColorData")


        array_id = self.Data.VertexID.generate()

        num_elements = len(color_array)

        writer.moveIn("Array TRUE ArrayID %d Vec4fArray %d" %(array_id, num_elements))

        for v in color_array:
            writer.writeLine("%f %f %f %f" %(v[0], v[1], v[2], v[3]))

        writer.moveOut("Array TRUE ArrayID %d Vec4fArray %d" %(array_id, num_elements))


        writer.writeLine("Indices FALSE")

        if num_elements == 1 :
            writer.writeLine("Binding BIND_OVERALL")
        else:
            writer.writeLine("Binding BIND_PER_VERTEX")

        writer.writeLine("Normalize 0")


        writer.moveOut("ColorData")




        uv_array_list = self.readUVArray()

        if uv_array_list and uv_array_list != []:

            num_tex = len(uv_array_list)

            writer.moveIn("TexCoordData %d" %num_tex)

            for uv_array in uv_array_list:

                writer.moveIn("Data") ;

                array_id = self.Data.VertexID.generate()
                num_elements = len(uv_array)

                writer.moveIn("Array TRUE ArrayID %d Vec2fArray %d" %(array_id, num_elements))

                for uv in uv_array:
                    writer.writeLine("%f %f" %(uv[0], uv[1]))

                writer.moveOut("Array TRUE ArrayID %d Vec2fArray %d" %(array_id, num_elements))


                writer.writeLine("Indices FALSE")
                writer.writeLine("Binding BIND_PER_VERTEX")
                writer.writeLine("Normalize 0")

                writer.moveOut("Data") ;



            writer.moveOut("TexCoordData %d" %num_tex)
############################################################################




############################################################################
    def readVertexArray(self):

        vertex_array = []

        faces = self.BlenderObject.polygons

        vertices = self.BlenderObject.vertices

        cur_face = 0

        for f in faces:

            if len(f.vertices) == 3:
                vertex_array.append( Vector(vertices[f.vertices[0]].co) )
                vertex_array.append( Vector(vertices[f.vertices[1]].co) )
                vertex_array.append( Vector(vertices[f.vertices[2]].co) )

            elif len(f.vertices) == 4:
                vertex_array.append( Vector(vertices[f.vertices[0]].co) )
                vertex_array.append( Vector(vertices[f.vertices[1]].co) )
                vertex_array.append( Vector(vertices[f.vertices[2]].co) )
                vertex_array.append( Vector(vertices[f.vertices[0]].co) )
                vertex_array.append( Vector(vertices[f.vertices[2]].co) )
                vertex_array.append( Vector(vertices[f.vertices[3]].co) )

            else:
                print("OOE Unhandled polygon type in %s, face: %d, num vertices: %d" % (self.BlenderObject.name, cur_face, len(f.vertices)))


            cur_face += 1

        return vertex_array
############################################################################




############################################################################
    def readNormalArray(self):
        normal_array = []


        faces = self.BlenderObject.polygons

        vertices = self.BlenderObject.vertices

        cur_face = 0

        for f in faces:

            if len(f.vertices) == 3:
                if f.use_smooth:
                    normal_array.append( Vector(vertices[f.vertices[0]].normal) )
                    normal_array.append( Vector(vertices[f.vertices[1]].normal) )
                    normal_array.append( Vector(vertices[f.vertices[2]].normal) )
                else:
                    normal_array.append( Vector(f.normal) )
                    normal_array.append( Vector(f.normal) )
                    normal_array.append( Vector(f.normal) )


            elif len(f.vertices) == 4:
                if f.use_smooth:
                    normal_array.append( Vector(vertices[f.vertices[0]].normal) )
                    normal_array.append( Vector(vertices[f.vertices[1]].normal) )
                    normal_array.append( Vector(vertices[f.vertices[2]].normal) )
                    normal_array.append( Vector(vertices[f.vertices[0]].normal) )
                    normal_array.append( Vector(vertices[f.vertices[2]].normal) )
                    normal_array.append( Vector(vertices[f.vertices[3]].normal) )
                else:
                    normal_array.append( Vector(f.normal) )
                    normal_array.append( Vector(f.normal) )
                    normal_array.append( Vector(f.normal) )
                    normal_array.append( Vector(f.normal) )
                    normal_array.append( Vector(f.normal) )
                    normal_array.append( Vector(f.normal) )

            else:
                print("Unhandled polygon type in %s, face: %d, num vertices: %d" % (self.BlenderObject.name, cur_face, len(f.vertices)))

            cur_face += 1

        return normal_array
############################################################################




############################################################################
    def readColorArray(self):

        color_array = []

        self.BlenderObject.update(calc_tessface=True, calc_edges=True)
        vcs = self.BlenderObject.tessface_vertex_colors

        if len(self.BlenderObject.materials) > 0 and self.BlenderObject.materials[0]  and  len(vcs) > 0 :

            faces = self.BlenderObject.polygons
            vertices = self.BlenderObject.vertices

            cur_face = 0

            for f in faces:
                if len(f.vertices) == 3:

                    color = vcs[0].data[ f.index ].color1
                    color_array.append( [color.r, color.g, color.b, 1.0] )


                    color = vcs[0].data[ f.index ].color2
                    color_array.append( [color.r, color.g, color.b, 1.0] )


                    color = vcs[0].data[ f.index ].color3
                    color_array.append( [color.r, color.g, color.b, 1.0] )


                elif len(f.vertices) == 4:

                    color = vcs[0].data[ f.index ].color1
                    color_array.append( [color.r, color.g, color.b, 1.0] )


                    color = vcs[0].data[ f.index ].color2
                    color_array.append( [color.r, color.g, color.b, 1.0] )


                    color = vcs[0].data[ f.index ].color3
                    color_array.append( [color.r, color.g, color.b, 1.0] )


                    color = vcs[0].data[ f.index ].color1
                    color_array.append( [color.r, color.g, color.b, 1.0] )


                    color = vcs[0].data[ f.index ].color3
                    color_array.append( [color.r, color.g, color.b, 1.0] )


                    color = vcs[0].data[ f.index ].color4
                    color_array.append( [color.r, color.g, color.b, 1.0] )

                else:
                    print("Unhandled polygon type in %s, face: %d, num vertices: %d" % (self.BlenderObject.name, cur_face, len(f.vertices)))

                cur_face += 1

        elif len(self.BlenderObject.materials) > 0 :
            c = []
            c.append( self.BlenderObject.materials[0].diffuse_color.r )
            c.append( self.BlenderObject.materials[0].diffuse_color.g )
            c.append( self.BlenderObject.materials[0].diffuse_color.b )
            c.append( self.BlenderObject.materials[0].alpha )

            color_array.append(c)

        else:
            c = []
            c.append( 0.8 )
            c.append( 0.8 )
            c.append( 0.8 )
            c.append( 1.0 )

            color_array.append(c)


        return color_array
############################################################################




############################################################################
    def readUVArray(self):
        uv_array = []


        self.BlenderObject.update(calc_tessface=True, calc_edges=True)


        faces = self.BlenderObject.polygons
        layers = self.BlenderObject.uv_layers


        if len(layers) == 0:
            return uv_array


        for i in range(0, len(layers), 1):
            uv_array.append([])
        #uv_array.append([])

        cur_face = 0

        for f in faces:
            for t in range(0, len(layers), 1):

                loop = f.loop_indices

                if len(loop) == 3:
                    uv_array[t].append( ( layers[t].data[ loop[0] ].uv[0], layers[t].data[ loop[0] ].uv[1] ) )
                    uv_array[t].append( ( layers[t].data[ loop[1] ].uv[0], layers[t].data[ loop[1] ].uv[1] ) )
                    uv_array[t].append( ( layers[t].data[ loop[2] ].uv[0], layers[t].data[ loop[2] ].uv[1] ) )

                elif len(loop) == 4:
                    uv_array[t].append( ( layers[t].data[ loop[0] ].uv[0], layers[t].data[ loop[0] ].uv[1] ) )
                    uv_array[t].append( ( layers[t].data[ loop[1] ].uv[0], layers[t].data[ loop[1] ].uv[1] ) )
                    uv_array[t].append( ( layers[t].data[ loop[2] ].uv[0], layers[t].data[ loop[2] ].uv[1] ) )
                    uv_array[t].append( ( layers[t].data[ loop[0] ].uv[0], layers[t].data[ loop[0] ].uv[1] ) )
                    uv_array[t].append( ( layers[t].data[ loop[2] ].uv[0], layers[t].data[ loop[2] ].uv[1] ) )
                    uv_array[t].append( ( layers[t].data[ loop[3] ].uv[0], layers[t].data[ loop[3] ].uv[1] ) )


                else:
                        print("Unhandled polygon type in %s, face: %d, num vertices: %d" % (self.BlenderObject.name, cur_face, len(loop)))


            cur_face = cur_face + 1



        return uv_array
############################################################################




# ........................................................................ #
############################################################################
